import org.w3c.dom.ls.LSOutput;
import java.util.Scanner;
public class J20250328{


//三、方法
//3.1 什么是⽅法(method)

//⽅法就是⼀个代码⽚段.类似于C语⾔中的"函数"。⽅法存在的意义(不要背,重在体会):
//1. 是能够模块化的组织代码(当代码规模⽐较复杂的时候).
//2. 做到代码被重复使⽤,一份代码可以在多个位置使⽤.
//3. 让代码更好理解更简单.
//4. 直接调⽤现有⽅法开发,不必重复造轮⼦.




//3.2⽅法定义
    //    修饰符 返回值类型 ⽅法名称([参数类型 形参 ...]){
    //        ⽅法体代码;
    //        [return 返回值];
    //    }


    //输出一个数的每一位数字（方法1）
    public static void print(int n)  {
        while (n != 0){
            System.out.print(n%10 + " ");
            n /= 10;
        }
    }
    //调用方法1 main + 方法名
    public static void main1(String[] args) {
        print(123);
    }


    //模拟密码登录（方法2）
    public static void login(){
        Scanner scanner = new Scanner(System.in);
        int count = 3;
        while (count != 0){
            System.out.println("请输入你的密码！");
            String pass = scanner.nextLine();
            //在Java中写输入值的时候不能写成 if(pass == "6666666") 否则输入对的密码也无法登录成功
            if (pass.equals ("666666")){
                System.out.println("登陆成功！");
                return ;
            }
            count--;
            System.out.println("你还有" + count + "次机会！");
        }
    }
    //调用方法2
    public static void main2(String[] args) {
        login();
    }





//3.3 书写⽅法的⽰例

    //判断是否是闰年（方法3）
    public static boolean isLeapYear(int year){
        if ((0 == year % 4 && 0 != year %100) || 0 == year % 400){
            System.out.println("是闰年！");
            return true;
        }else{
            System.out.println("不是闰年！");
            return false;
        }
    }
    //调用方法3 main + 类型 + 定义 + 打印
    public static void main3(String[] args) {
        boolean flg = isLeapYear(2025);
        System.out.println(flg);
    }



    //实现两个数的相加（方法4）
    public static  int add1(int x, int y){
        System.out.println("x = " + x);
        System.out.println("y = " + y);
        return x + y;
    }
    //调用方法4
    public static void main4(String[] args) {
        int whole = add1(2,6);
        System.out.println("和为 " + whole);
    }
    //    【注意事项】
    //1. 修饰符：现阶段直接使⽤public static固定搭配
    //2. 返回值类型：如果⽅法有返回值，返回值类型必须要与返回的实体类型⼀致，如果没有返回值，必须写成void
    //3. ⽅法名字：采⽤⼩驼峰命名
    //4. 参数列表：如果⽅法没有参数，()中什么都不写，如果有参数，需指定参数类型，多个参数之间使⽤逗号隔开
    //5. ⽅法体：⽅法内部要执⾏的语句
    //6. 在Java当中，⽅法必须写在类当中
    //7. 在Java当中，⽅法不能嵌套定义
    //8. 在Java当中，没有⽅法声明⼀说





//3.4 ⽅法的调⽤

    //方法的定义
    public static int add2(int x, int y){
        return x + y;
    }
    public static void main5(String[] args) {
        //调用方法
        int ret = add2(1, 2);
        System.out.println("ret = " + ret);

        int ret2 = add2(3, 4);
        System.out.println("ret2 = " + ret2);
    }
    //总结：
    //1. 定义⽅法的时候,不会执⾏⽅法的代码.只有调⽤的时候才会执⾏.
    //2. 调⽤⽅法的时候，需要使⽤⽅法名+参数列表的形式进⾏调⽤
    //3. 如果⽅法有返回值，需要接收返回值结果





//3.5方法调用过程

    public static void main6(String[] args) {
        int a = 10;
        int b = 20;
        System.out.println("第一次调用方法之前");
        int ret = add3(a, b);
        System.out.println("第一次调用方法之后");
        System.out.println("ret = " + ret);

        System.out.println("第二次调用方法之前");
        ret = add3(30,50);
        System.out.println("第二次调用方法之后");
        System.out.println("ret = " + ret);
    }
    public static int add3(int x,int y){
        System.out.println("调用方法中 x = " + x + " y = " + y);
        return x + y;
    }


    //计算阶乘之和 1！+ 2！+ 3！+ 4！+5！
    public static void main7(String[] args) {
        int sum = 0;
        for (int i = 1; i <= 5; i++){
            sum += fac(i);
        }
        System.out.println("sum = " + sum);
    }
    public  static int fac(int n){
        System.out.println("计算 n 的阶乘中 n == " + n);
        int result = 1;
        for (int i = 1; i <= n; i++){
            result *= i;
        }
        return result;
    }
    //总结：
    //1. ⼀个⽅法可以被多次调⽤
    //2. 使⽤⽅法,避免使⽤⼆重循环,让代码更简单清晰.





//3.6形参与实参的关系

    //⽅法的形参相当于数学函数中的⾃变量，⽐如：1+2+3+…+n的公式为sum(n)=((1+n)*n)/2
    //Java中⽅法的形参就相当于sum函数中的⾃变量n，⽤来接收sum函数在调⽤时传递的值的。
    // 形参的名字可以随意取，对⽅法都没有任何影响，形参只是⽅法在定义时需要借助的⼀个变量，⽤来保存⽅法在调⽤时传递过来的值。

    public static void main8(String[] args) {
        //实参传值给形参，必须做到类型匹配，顺序匹配，个数匹配
        //调用方法
        int ret = getSum(10);              //10是实参，在方法调用时。形参N用来保存10
        System.out.println("ret = " + ret);   //N是形参
    }
    public static int getSum(int N){
        return (1 + N ) * N / 2;
    }
    //在Java中，实参的值永远都是拷⻉到形参中，形参和实参本质是两个实体
    //实参传值给形参，必须做到类型匹配，顺序匹配，个数匹配


    //例题：交换实参的值
    public static void main9(String[] args) {
        int a = 10;
        int b = 20;
        System.out.println("交换前：a = " + a + " b = " + b);
        swap(a, b);
        System.out.println("交换后：a = " + a + " b = " + b);
    }
    public static void swap(int x, int y){
        //交换形参x和y的值
        int tmp = x;
        x = y;
        y = tmp;
    }
    //注意：
    // 实参a和b是main⽅法中的两个变量，其空间在main⽅法的栈(⼀块特殊的内存空间)中，
    // ⽽形参x和y是swap⽅法中的两个变量，x和y的空间在swap⽅法运⾏时的栈中，
    // 因此：实参a和b与形参x和y是两个没有任何关联性的变量，
    // 在swap⽅法调⽤时，只是将实参a和b中的值拷⻉了⼀份传递给了形参x和y，
    // 因此对形参x和y操作不会对实参a和b产⽣任何影响。
    //在Java当中是⽆法获取栈上的局部变量的地址的，如果要发⽣实参的交换，我们需要具备类和对象的知识。





//3.7关于返回值

    //⽅法的返回值是⽤来接收⽅法运⾏之后，需要传递出去的值的。有的⽅法有返回值，有的⽅法没有返回值。
    //如果有返回值的情况下，我们需要注意返回值的数据类型需要匹配。
    public static void main10(String[] args) {
        //调用方法
        int ret = getSum(10);// 10是实参，在方法调用时，形参N用来保存10
        System.out.println("ret = " + ret);
    }
    public static int getSum2(int N){ //N是形参
        return (1+N)*N / 2;
    }

    //该⽅法getSum返回值是int，需要使⽤int来进⾏接收
    //如果没有返回值，我们需要注意，不能接受该⽅法返回值，返回值类型为void
    public static void main11(String[] args) {
        int a = 10;
        int b = 20;
        print(a, b);
        int ret = print(a, b);
    }
    public static int print(int x, int y){
        System.out.println("x = " + x + " y = " + y);
        return 0;
    }


    //返回值可以⽀持链式表达式：
    //题目：计算连续数字1到N之间的和，将其计算得到的结果扩⼤为2倍
    public static void main12(String[] args) {
        //调用方法
        int ret = getSum3(10) * 2;
        System.out.println("ret = " + ret);
    }
    public static int getSum3(int N){  // N是形参
        return (1+N)*N / 2;
    }
    //上述代码中：getSum(10) * 2利⽤了⽅法的返回值作为新的表达式的⼀个值参与了运算
    //总结：
    // 1.返回值在接收过程当中需要匹配
    // 2.没有返回值的情况下，⽅法的返回值类型为void
    // 3.⼀个⽅法是否有返回值需要视情况⽽定





//四、方法重载
//4.1为什么需要方法重载

    //如下代码的错误: 不兼容的类型: 从double转换到int可能会有损失
    /*public static void main(String[] args) {
        int a = 10;
        int b = 20;
        int ret = add(a, b);
        System.out.println("ret = " + ret);

        double a2 = 10.5;
        double b2 = 20.5;
        double ret2 = add(a2, b2);
        System.out.println("ret2 = " + ret2);
    }
    public static int add4(int x, int y){
        return x + y;
    }*/

    //由于参数类型不匹配,所以不能直接使⽤现有的add⽅法.
    //⼀种⽐较简单粗暴的解决⽅法如下：
    public static void main13(String[] args) {
        int a = 10;
        int b = 20;
        int ret = addInt(a, b);
        System.out.println("ret = " + ret);
        double a2 = 10.5;
        double b2 = 20.5;
        double ret2 = addDouble(a2, b2);
        System.out.println("ret2 = " + ret2);
    }
    public static int addInt(int x, int y) {
        return x + y;
    }
    public static double addDouble(double x, double y) {
        return x + y;
    }



    //4.2 ⽅法重载的概念
    //在Java中，如果多个⽅法的名字相同，参数列表不同，则称该⼏种⽅法被重载了。
    public static void main14(String[] args) {
        add4(1, 2);
        add4(1.5, 2.5);
        add4(1.5, 2.5, 3.5);
    }
    public static int add4(int x, int y){
        return x + y;
    }
    public static double add4(double x, double y){
        return x + y;
    }
    public static double add4(double x, double y, double z){
        return x + y + z;
    }
    //注意：
    //1. ⽅法名必须相同
    //2. 参数列表必须不同(参数的个数不同、参数的类型不同、类型的次序必须不同)
    //3. 与返回值类型是否相同⽆关
    //4. 编译器在编译代码时，会对实参类型进⾏推演，根据推演的结果来确定调⽤哪个⽅法

    // 注意：两个⽅法如果仅仅只是因为返回值类型不同，是不能构成重载的
    /*public static void main(String[] args) {
        int a = 10;
        int b = 20;
        int ret = add5(a, b);
        System.out.println("ret = " + ret);
    }
    public static int add5(int x, int y){
        return x + y;
    }
    public static double add5(int x, int y){
        return x + y;
    }*/



//4.3 ⽅法签名
    //在同⼀个作⽤域中不能定义两个相同名称的标识符。⽐如：⽅法中不能定义两个名字⼀样的变量，那
    //为什么类中就可以定义⽅法名相同的⽅法呢？
    //⽅法签名即：经过编译器编译修改过之后⽅法最终的名字。具体⽅式：⽅法全路径名+参数列表，构成
    //⽅法完整的名字。https://docs.oracle.com/javase/specs/jls/se17/html/jls-8.html#jls-8.4.2


    public static int add(int x, int y){
        return x + y;
    }
    public static double add(double x, double y){
        return x + y;//定义方法
    }
    public static void main15(String[] args) {

        int ret = add(1,2);//调用方法
        System.out.println(ret);

        double ret2 = add(1.5, 2.5);
        System.out.println(ret2);
    }

}